package main

import "fmt"

/**
 * defer关键字：https://tiancaiamao.gitbooks.io/go-internals/content/zh/03.4.html
 * defer 是在 return 之前 执行
 * 转换公式：
 * 1、返回值 = xxx
 * 2、调用defer函数
 * 3、空的return
 */

func fun1() (result int) {
	// 匿名函数执行时机：
	defer func() {
		result++
	}()
	return 0
}

func fun1Transfer() (result int) {
	result = 0
	func() {
		result++
	}()
	//return 语句没有指定具体的返回值表达式，因此它是一个空的 return 语句。在 Go 语言中，你可以使用空的 return 语句来显式地返回命名返回值的当前值，而不必提供具体的表达式。这是 Go 语言的一个方便之处，因为命名返回值在函数体内可以被修改，而在函数返回时，它们的当前值就成了返回值。
	return
}

func fun2() (r int) {
	t := 5
	defer func() {
		t = t + 5
	}()
	return t
}

func fun2Transfer() (r int) {
	t := 5
	r = t    //赋值指令
	func() { //defer被插入到赋值与返回之间执行，这个例子中返回值r没被修改过
		t = t + 5
	}()
	return //空的return指令
}

func fun3() (r int) {
	defer func(r int) {
		r = r + 5
	}(r)
	return 1
}

func fun3Transfer() (r int) {
	r = 1         //给返回值赋值
	func(r int) { //这里改的r是传值传进去的r，不会改变要返回的那个r值
		r = r + 5
	}(r)
	return //空的return
}

func main() {
	//当函数 fun1() 被调用时，它声明了一个整数变量 result 作为返回值，并将其初始化为 0。
	//value := fun1()
	//fmt.Println(value)
	//
	//valueTransfer := fun1Transfer()
	//fmt.Println(valueTransfer)

	value2 := fun2()
	fmt.Println(value2)

	value2Transfer := fun2Transfer()
	fmt.Println(value2Transfer)

	//value3 := fun3Transfer()
	//fmt.Println(value3)
}
